import json
import os
import re
import unicodedata
from datetime import datetime
from openpyxl import load_workbook

# ==================== 配置区域 ====================
CONFIG = {
    "xlsx_path": "all.xlsx",
    "sheet_arb_mapping": {
        "de": "../lib/l10n/intl_de.arb",    # 德语sheet → 德语ARB
        "es": "../lib/l10n/intl_es.arb",    # 西班牙语sheet → 西班牙语ARB
        "it": "../lib/l10n/intl_it.arb",    # 意大利语sheet → 意大利语ARB
        "fr": "../lib/l10n/intl_fr.arb",    # 法语sheet → 法语ARB
        "pt": "../lib/l10n/intl_pt.arb"     # 葡萄牙语sheet → 葡萄牙语ARB
    },
    "source_col": 0,  # 英文列索引
    "trans_col": 1,   # 翻译列索引
    "debug": False    # 开启调试查看字符编码
}
# =================================================

def normalize_for_matching(s):
    """
    生成用于匹配的标准化字符串：
    - 移除所有换行符（\n、\\n）和连续空格
    - 仅保留文字内容用于匹配判断
    """
    if not isinstance(s, str):
        return ""
    
    # 标准化Unicode字符
    normalized = unicodedata.normalize('NFC', s)
    # 移除所有换行符（包括实际换行和转义换行）
    normalized = normalized.replace('\n', '').replace('\\n', '')
    # 移除不可见字符
    normalized = re.sub(r'[^\w\s!"#$%&\'()*+,-./:;<=>?@[\]^_`{|}~]', '', normalized)
    # 合并连续空格并去除首尾空格
    return re.sub(r'\s+', ' ', normalized).strip()

def debug_chars(s, label="字符串"):
    """调试：显示字符串的原始内容和匹配键"""
    if not CONFIG["debug"]:
        return
    print(f"\n{label} 原始值：'{s}'")
    print(f"字符编码：", [f"'{c}' (0x{ord(c):04X})" for c in s])
    print(f"匹配键值：'{normalize_for_matching(s)}'")

def load_sheet_translations(xlsx_path, sheet_name):
    """
    读取XLSX翻译数据：
    - 保留翻译的原始格式（包括换行符）
    - 生成英文的匹配键（用于后续匹配ARB中的英文）
    """
    # 映射关系：{英文匹配键: 原始翻译值（完全保留格式）}
    translations = {}
    # 翻译内容的匹配键集合（用于检查缺失）
    trans_match_keys = set()
    
    workbook = load_workbook(xlsx_path, read_only=True, data_only=True)
    if sheet_name not in workbook.sheetnames:
        workbook.close()
        raise Exception(f"XLSX中不存在sheet '{sheet_name}'")
    
    sheet = workbook[sheet_name]
    
    for row_num, row in enumerate(sheet.iter_rows(min_row=2, values_only=True), start=2):
        # 处理英文（源语言）
        if CONFIG["source_col"] >= len(row):
            print(f"    警告：sheet '{sheet_name}' 行 {row_num} 源语言列缺失，已跳过")
            continue
        
        english_raw = row[CONFIG["source_col"]]
        english_str = str(english_raw) if english_raw is not None else ""
        english_match_key = normalize_for_matching(english_str)
        debug_chars(english_str, f"XLSX行 {row_num} 英文原始值")
        
        if not english_match_key:
            print(f"    警告：sheet '{sheet_name}' 行 {row_num} 英文值为空，已跳过")
            continue
        
        # 处理翻译值（完全保留原始格式，包括换行符）
        if CONFIG["trans_col"] >= len(row):
            print(f"    警告：sheet '{sheet_name}' 行 {row_num} 翻译列缺失，已跳过")
            continue
        
        trans_raw = row[CONFIG["trans_col"]]
        trans_str = str(trans_raw) if trans_raw is not None else ""
        trans_match_key = normalize_for_matching(trans_str)
        debug_chars(trans_str, f"XLSX行 {row_num} 翻译原始值")
        
        if trans_match_key:
            # 存储英文匹配键到原始翻译值的映射（翻译值完全不处理）
            translations[english_match_key] = trans_str
            trans_match_keys.add(trans_match_key)
    
    workbook.close()
    return translations, trans_match_keys

def process_arb(sheet_name, arb_path, translations, trans_match_keys):
    """
    处理ARB文件：
    - 仅当英文内容（忽略换行）匹配时，用XLSX中的原始翻译（保留格式）替换
    - 翻译文案完全不改动，包括换行符、空格等格式
    """
    try:
        if not os.path.exists(arb_path):
            print(f"  错误：ARB文件不存在 - {arb_path}，已跳过")
            return
        
        # 读取ARB原始数据（保留所有格式）
        with open(arb_path, 'r', encoding='utf-8') as f:
            arb_data = json.load(f)
        
        updated_count = 0
        # 遍历ARB中的所有键值对
        for key, value in arb_data.items():
            # 跳过注释键（@开头）和非字符串值
            if key.startswith('@') or not isinstance(value, str):
                continue
            
            # 生成ARB中当前值的匹配键（用于匹配英文）
            value_match_key = normalize_for_matching(value)
            debug_chars(value, f"ARB key '{key}' 原始值")
            
            # 当英文内容匹配时，用XLSX的原始翻译替换（完全保留格式）
            if value_match_key in translations:
                xlsx_trans = translations[value_match_key]
                # 仅在内容不同时更新（严格对比原始字符串）
                if value != xlsx_trans:
                    arb_data[key] = xlsx_trans  # 直接赋值原始翻译，不做任何处理
                    updated_count += 1
                    print(f"  已更新：{key}（原始：'{value}' → 新值：'{xlsx_trans}'）")
        
        # 保存更新后的ARB（保留原始格式）
        if updated_count > 0:
            with open(arb_path, 'w', encoding='utf-8') as f:
                json.dump(arb_data, f, ensure_ascii=False, indent=2)
            print(f"  完成！共更新 {updated_count} 条翻译（均保留原始格式）")
        else:
            print(f"  没有需要更新的翻译")
        
        # 检查未匹配的翻译（仅文字内容不同时视为不匹配）
        missing = []
        untranslated_keys = set()
        for key, value in arb_data.items():
            if key.startswith('@') or not isinstance(value, str):
                continue
            
            value_match_key = normalize_for_matching(value)
            if value_match_key not in trans_match_keys:
                missing.append({
                    "key": key,
                    "original_value": value,  # 原始值（含格式）
                    "content_key": value_match_key  # 仅文字内容（用于核对）
                })
                untranslated_keys.add(value_match_key)
        
        # 生成缺失翻译报告
        base_name = os.path.splitext(os.path.basename(arb_path))[0]
        output_path = os.path.join(os.path.dirname(arb_path), f"{base_name}_missing.txt")
        
        if missing:
            print(f"  发现 {len(missing)} 个未匹配的翻译（文字内容不同），已保存到：{output_path}")
            
            with open(output_path, 'w', encoding='utf-8') as f:
                f.write(f"# {sheet_name} 未匹配翻译（共 {len(missing)} 个）\n")
                f.write(f"# 生成时间：{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
                f.write(f"# 说明：仅文字内容不同视为未匹配，忽略换行/空格差异\n\n")
                
                # 详细条目（保留原始格式）
                f.write("## 详细未匹配项（含原始格式）\n")
                for i, item in enumerate(sorted(missing, key=lambda x: x["key"]), 1):
                    f.write(f"{i}. key: {item['key']}\n")
                    f.write(f"   原始值: '{item['original_value']}'\n")
                    f.write(f"   文字内容: '{item['content_key']}'\n\n")
                
                # 未匹配的文字内容汇总
                f.write("\n" + "="*50 + "\n")
                f.write("## 未匹配的文字内容（忽略格式）\n")
                for idx, content in enumerate(sorted(untranslated_keys), 1):
                    f.write(f"{idx}. '{content}'\n")
        else:
            print(f"  所有翻译文字内容均匹配（忽略格式差异）")
            if os.path.exists(output_path):
                os.remove(output_path)
    
    except Exception as e:
        print(f"  处理出错：{str(e)}")

def main():
    try:
        if not os.path.exists(CONFIG["xlsx_path"]):
            print(f"错误：XLSX文件不存在 - {CONFIG['xlsx_path']}")
            return
        
        sheet_names = list(CONFIG["sheet_arb_mapping"].keys())
        print(f"开始处理XLSX：{CONFIG['xlsx_path']}（sheet：{', '.join(sheet_names)}）\n")
        
        for i, (sheet_name, arb_path) in enumerate(CONFIG["sheet_arb_mapping"].items(), 1):
            print(f"===== 处理第 {i}/{len(sheet_names)} 个sheet：{sheet_name} =====")
            print(f"  ARB文件：{arb_path}")
            
            try:
                translations, trans_match_keys = load_sheet_translations(
                    CONFIG["xlsx_path"], sheet_name
                )
                print(f"  加载了 {len(translations)} 条翻译数据（均保留原始格式）")
            except Exception as e:
                print(f"  加载失败：{str(e)}")
                continue
            
            process_arb(sheet_name, arb_path, translations, trans_match_keys)
        
        print("\n所有处理完成！")
    
    except Exception as e:
        print(f"错误：{str(e)}")

if __name__ == "__main__":
    main()